package com.qianfeng.smsplatform.api.service.impl;

//
//                            _ooOoo_  
//                           o8888888o  
//                           88" . "88  
//                           (| -_- |)  
//                            O\ = /O  
//                        ____/`---'\____  
//                      .   ' \\| |// `.  
//                       / \\||| : |||// \  
//                     / _||||| -:- |||||- \  
//                       | | \\\ - /// | |  
//                     | \_| ''\---/'' | |  
//                      \ .-\__ `-` ___/-. /  
//                   ___`. .' /--.--\ `. . __  
//                ."" '< `.___\_<|>_/___.' >'"".  
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |  
//                 \ \ `-. \_ __\ /__ _/ .-` / /  
//         ======`-.____`-.___\_____/___.-`____.-'======  
//                            `=---='  
//  
//         .............................................  
//                  佛祖镇楼                  BUG辟易  
//          佛曰:  
//                  写字楼里写字间，写字间里程序员；  
//                  程序人员写程序，又拿程序换酒钱。  
//                  酒醒只在网上坐，酒醉还来网下眠；  
//                  酒醉酒醒日复日，网上网下年复年。  
//                  但愿老死电脑间，不愿鞠躬老板前；  
//                  奔驰宝马贵者趣，公交自行程序员。  
//                  别人笑我忒疯癫，我笑自己命太贱；  
//  


import com.qianfeng.smsplatform.api.exceptions.MyBaseException;
import com.qianfeng.smsplatform.api.service.IPushSubmitToQueueService;
import com.qianfeng.smsplatform.api.service.ISmsCheckService;
import com.qianfeng.smsplatform.api.service.api.CacheService;
import com.qianfeng.smsplatform.api.utils.PhoneFormatCheckUtil;
import com.qianfeng.smsplatform.common.constants.CacheConstants;
import com.qianfeng.smsplatform.common.constants.InterfaceExceptionDict;
import com.qianfeng.smsplatform.common.model.Standard_Submit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created by jackiechan on 2021/7/14/20:34
 *
 * @Author jackiechan
 */
@Service
public class SmsCheckServiceImpl implements ISmsCheckService {

    private CacheService cacheService;

    private IPushSubmitToQueueService submitToQueueService;
    @Autowired
    public void setSubmitToQueueService(IPushSubmitToQueueService submitToQueueService) {
        this.submitToQueueService = submitToQueueService;
    }

    @Autowired
    public void setCacheService(CacheService cacheService) {
        this.cacheService = cacheService;
    }

    @Override
    public  List<String> checkSms(String clientId, String pwd, String srcId, String mobile, String content, String ip) {
        //我们在这里要判断用户账号和密码, 真实的账号和密码保存在什么地方?怎么获取
        //数据保存在数据库? redis?
        //从redis获取用户的数据,然后进行账号和密码的校验
        Map map = cacheService.hmget(CacheConstants.CACHE_PREFIX_CLIENT + clientId);
      //  System.err.println(map);
        if (map == null || map.size() == 0) {
            //用户不存在
            throw new MyBaseException("clientid错误", InterfaceExceptionDict.RETURN_STATUS_CLIENTID_ERROR);
        }else{
            //查询到了用户的信息
            //比较密码,注意用户传递的是一个明文,但是我们实际上数据库中存的是md5,需要先进行转换
            String paramMd5 = DigestUtils.md5DigestAsHex(pwd.getBytes(StandardCharsets.UTF_8));//将用户传递的密码转成md5

            String pwd1 = (String) map.get("pwd");
            if (!pwd1.equalsIgnoreCase(paramMd5)) {
                throw new MyBaseException("密码错误", InterfaceExceptionDict.RETURN_STATUS_PWD_ERROR);
            }

            //判断ip
            //看看发起请求的ip在不在允许的ip白名单中
            //获取到用户的真正的ip,然后从redis中获取用户的允许的ip,然后看看当前的ip在不在这个内容中
            String ipaddress = (String) map.get("ipaddress");//用户允许的ip
            if (!ipaddress.contains(ip)){
                //用户的访问ip不在允许的列表中
                throw new MyBaseException("来源ip不在白名单中", InterfaceExceptionDict.RETURN_STATUS_IP_ERROR);

            }


            //下行id校验
            Long srcIdLong = null;

            try {
                srcIdLong= Long.parseLong(srcId);
            }catch (Exception e){
               e.printStackTrace();
                throw new MyBaseException("下行ID错误", InterfaceExceptionDict.RETURN_STATUS_SRCID_ERROR);

            }


            //判断手机号是不是合适的手机号
            //这个手机号可能传递了很多个,那么我们需要拆开后再进行判断,怎么知道每个手机号, 我们要求传递的时候通,来进行分割
            if (StringUtils.isEmpty(mobile)) {
                throw new MyBaseException("手机号为空", InterfaceExceptionDict.RETURN_STATUS_MOBILE_ERROR);

            }
            String[] mobiles = mobile.split(",");

            //传递的很多个手机号,有的可能是合规的手机号,有的可能并不是真正的手机号,需要我们区分
            //当我们区分出来之后怎么办? 比如用户要群发短信,有一个手机号不合规,是全部拒绝还是出了不合规的都发出去
            //我们发现我们需要将合规的手机号发出去,不合规的给用户返回,我们需要区分出来,需要分成两组集合
            List<String> okList = Arrays.stream(mobiles).filter(PhoneFormatCheckUtil::isPhoneLegal).collect(Collectors.toList());//合规的手机号
            List<String> failList = Arrays.stream(mobiles).filter(num->!PhoneFormatCheckUtil.isPhoneLegal(num)).collect(Collectors.toList());//合规的手机号

            //我们经过分析得出我们不需要让客户实时等待结果,我们只需要在处理完成后通知用户结果即可,所以发送短息的操作不需要同步处理,所以可是使用MQ

            Long finalSrcIdLong = srcIdLong;
            List<Standard_Submit> submitList = okList.stream().map(num -> {
                Standard_Submit standard_submit = new Standard_Submit();
                standard_submit.setClientID(Integer.parseInt(clientId));
                standard_submit.setSrcSequenceId(finalSrcIdLong);
                standard_submit.setDestMobile(num);
                standard_submit.setMessageContent(content);
                standard_submit.setSendTime(new Date());
                standard_submit.setSource((Integer) map.get("usertype"));
                return standard_submit;
            }).collect(Collectors.toList());

            submitToQueueService.sendMessage(submitList);//发送数据到mq


            return failList;
        }
    }
}
